package yartiss.gui.graphics;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.util.Arrays;
import java.util.Comparator;

import javax.swing.JDesktopPane;
import javax.swing.JInternalFrame;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;

import yartiss.gui.graphics.rendrerers.DefaultChartRendrer;
import yartiss.service.model.IChartModel;

@SuppressWarnings("serial")
public class JChartPane<E> extends JDesktopPane{

	private boolean isDebug = false;

	private IChartModel<E> model;
	private IChartRenderer<E> renderer  = new DefaultChartRendrer<E>();
	
	public JChartPane(IChartModel<E> model){
		super();
		setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
		setModel(model);
	}

	public void  setChartRenderer(IChartRenderer<E> renderer){
		this.renderer = renderer;
		reloadFrames();
	}

	private int openFrameCount = 0;

	private void addChart(E e){
		JInternalFrame frame = renderer.render(e, isDebug);
		add(frame);
		openFrameCount++;
	}


	public void setModel(IChartModel<E> model) {
		unregisterModelListeners();
		this.model = model;
		registerModelListeners();
		reloadFrames();
	}
	
	private void reloadFrames(){
		openFrameCount = 0;
		removeAll();
		if(model != null){
			for (E e : model.getAll()) {
				addChart(e);
			}
		}
		layoutChilds();
		repaint();
		revalidate();
	}
	
	private Comparator<Component> comparator = new Comparator<Component>() {
		@Override public int compare(Component o1, Component o2) {
			String text1 = o1  instanceof JInternalFrame ? ((JInternalFrame)o1).getTitle() : o1.getClass().getName(); 
			String text2 = o2  instanceof JInternalFrame ? ((JInternalFrame)o2).getTitle() : o2.getClass().getName();
			return text1.compareTo(text2);
		}
	};
	
	private void layoutChilds(){
		if( getComponentCount()==0)return;
		Dimension d = getSize();
		int nbPerLine = getComponentCount()/2 + getComponentCount()%2;
		int nbLines = 2;
		int widthUnit = d.width / nbPerLine;
		int heightUnit = (d.height-30) /nbLines;
		int i=0,x=0,y=0;
		Component [] childs = getComponents();
		Arrays.sort(childs,comparator);
		for (Component comp : childs) {
			i++;
			if(comp instanceof JInternalFrame)
				comp.setBounds(x, y, widthUnit, heightUnit);
			x += widthUnit;
			if(i % nbPerLine == 0){
				x = 0;
				y+=heightUnit; 
			}
		}
	}
	
	private Dimension oldSize = new Dimension();
	private int oldChildsCount = 0;
	@Override
	protected void paintChildren(Graphics g){
		Dimension d = getSize();
		if(d.height != oldSize.height || d.width != oldSize.width || oldChildsCount != getComponentCount()){
			layoutChilds();
			oldChildsCount  = getComponentCount();
			oldSize.setSize(d);
		}
		super.paintChildren(g);
	}

	private ListDataListener listener = new ListDataListener() {
		@Override	public void contentsChanged(ListDataEvent e) {reloadFrames();}
		@Override	public void intervalRemoved(ListDataEvent e) {reloadFrames();}
		@Override	public void intervalAdded(ListDataEvent e) {reloadFrames();}
	};
	
	

	private void registerModelListeners() {
		if(model != null)
			model.addListDataListener(listener);
	}

	private void unregisterModelListeners() {
		if(model != null)
			model.removeListDataListener(listener);
	}

	/**
	 * @return the isDebug
	 */
	public boolean isDebug() {
		return isDebug;
	}

	/**
	 * @param isDebug the isDebug to set
	 */
	public void setDebug(boolean isDebug) {
		this.isDebug = isDebug;
		reloadFrames();
	}
	
	
}
